<!DOCTYPE html>
<html lang="en-US" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>react18 | 前端码农</title>
    <meta name="description" content="前端码农手记">
    <link rel="preload stylesheet" href="/fe-handbook/document/assets/style.c131dda6.css" as="style">
    <script type="module" src="/fe-handbook/document/assets/app.fb33e324.js"></script>
    <link rel="preload" href="/fe-handbook/document/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
  <link rel="modulepreload" href="/fe-handbook/document/assets/chunks/framework.e1becf5d.js">
  <link rel="modulepreload" href="/fe-handbook/document/assets/chunks/theme.ebfdf2c7.js">
  <link rel="modulepreload" href="/fe-handbook/document/assets/pages_react_react.md.dd542d19.lean.js">
  <link rel="icon" type="image/svg+xml" href="images/logo.svg">
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-bffce215><!--[--><!--]--><!--[--><span tabindex="-1" data-v-73e3a132></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-73e3a132> Skip to content </a><!--]--><!----><header class="VPNav" data-v-bffce215 data-v-5bdc5df3><div class="VPNavBar has-sidebar" data-v-5bdc5df3 data-v-c388e33c><div class="container" data-v-c388e33c><div class="title" data-v-c388e33c><div class="VPNavBarTitle has-sidebar" data-v-c388e33c data-v-1ab7b21f><a class="title" href="/fe-handbook/document/" data-v-1ab7b21f><!--[--><!--]--><!--[--><img class="VPImage logo" src="/fe-handbook/document/images/logo.svg" alt data-v-dc109a54><!--]--><!--[-->前端码农<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-c388e33c><div class="curtain" data-v-c388e33c></div><div class="content-body" data-v-c388e33c><!--[--><!--]--><div class="VPNavBarSearch search" style="--vp-meta-key:&#39;Meta&#39;;" data-v-c388e33c><!----></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-c388e33c data-v-f732b5d0><span id="main-nav-aria-label" class="visually-hidden" data-v-f732b5d0>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/fe-handbook/document/" tabindex="0" data-v-f732b5d0 data-v-b7aed9c7 data-v-f3ed0000><!--[-->主页<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/fe-handbook/document/pages/guide.html" tabindex="0" data-v-f732b5d0 data-v-b7aed9c7 data-v-f3ed0000><!--[-->指南<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/fe-handbook/document/pages/updateLog.html" tabindex="0" data-v-f732b5d0 data-v-b7aed9c7 data-v-f3ed0000><!--[-->更新日志<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-c388e33c data-v-5e9f0637><label title="toggle dark mode" data-v-5e9f0637 data-v-67878c63><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-checked="false" data-v-67878c63 data-v-92d8f6fb><span class="check" data-v-92d8f6fb><span class="icon" data-v-92d8f6fb><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-67878c63><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-67878c63><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></label></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-c388e33c data-v-ef6192dc data-v-b8f6762d><!--[--><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-c388e33c data-v-c8c2ae4b data-v-6afe904b><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-6afe904b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-6afe904b><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-6afe904b><div class="VPMenu" data-v-6afe904b data-v-e42ed9b3><!----><!--[--><!--[--><!----><div class="group" data-v-c8c2ae4b><div class="item appearance" data-v-c8c2ae4b><p class="label" data-v-c8c2ae4b>Appearance</p><div class="appearance-action" data-v-c8c2ae4b><label title="toggle dark mode" data-v-c8c2ae4b data-v-67878c63><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-checked="false" data-v-67878c63 data-v-92d8f6fb><span class="check" data-v-92d8f6fb><span class="icon" data-v-92d8f6fb><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-67878c63><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-67878c63><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></label></div></div></div><div class="group" data-v-c8c2ae4b><div class="item social-links" data-v-c8c2ae4b><div class="VPSocialLinks social-links-list" data-v-c8c2ae4b data-v-b8f6762d><!--[--><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-c388e33c data-v-6bee1efd><span class="container" data-v-6bee1efd><span class="top" data-v-6bee1efd></span><span class="middle" data-v-6bee1efd></span><span class="bottom" data-v-6bee1efd></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav" data-v-bffce215 data-v-ba1b30d0><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-ba1b30d0><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-ba1b30d0><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-ba1b30d0>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-ba1b30d0 data-v-fb63c957><button data-v-fb63c957>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-bffce215 data-v-fe05da0a><div class="curtain" data-v-fe05da0a></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-fe05da0a><span class="visually-hidden" id="sidebar-aria-label" data-v-fe05da0a> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><!----><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/guide.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>开发指南</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>JavaScript高级程序设计</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/advancedProgramming/index.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>0.前言</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/advancedProgramming/chapterOne.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>1.什么是JavaScript</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/advancedProgramming/chapterTwo.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>2.HTML中的JavaScript</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/advancedProgramming/chapterThree.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>3.语言基础</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>vue技术栈</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/vue/vue2.0.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>vue2.0</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/vue/vue3.0.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>vue3.0</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/vue/vuex4.0.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>vuex4.0</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible has-active" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>react技术栈</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link is-active has-active" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/react/react.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>react18</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/react/redux.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>redux</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>nodejs技术栈</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/nodeJS/index.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>nodeJS</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/nodeJS/nest.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>nest</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>flutter</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/flutter/index.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>flutter</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>数据结构算法&设计模式</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/dataStructure.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>dataStructure</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/designPatterns.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>设计模式</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>js基础进阶</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/dataType.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>数据类型</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/typeConversion.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>数据类型转换</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/prototype.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>原型与原型链</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/scope.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>闭包</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/this.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>this指针</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/promotion.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>JS中的变量提升和函数提升</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/eventLoop.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>异步&事件循环机制</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/promise.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>promise</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/cookieLocal.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>cookie&local</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/arrayApi.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>arrayApi</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/regular.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>正则</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/coding.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>coding</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/typescript.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>typescript</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>前端综合</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/eightLeggedEssay.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>前端八股文</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/jsBase/binary.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>二进制</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/ssr.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>ssr</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/webpack.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>webpack</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/http.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>http</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/optimize.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>性能优化</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/xss-csrf.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>xss-csrf</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/linux.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>linux</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/nginx.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>nginx</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/git.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>git管理</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>工作复盘</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/stripe.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>stripe支付体检优化</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/interfaceSignatureDesign.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>接口签名设计</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/reduxpersistence.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>redux数据持久化</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/vuexpersistence.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>vuex数据持久化</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/reactSolt.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>react插槽设计</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/bigfileUpload.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>大文件上传</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/audio.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>音频录制</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/virtuaLlist.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>虚拟列表</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/imageCroppingCompression.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>图片裁剪&压缩</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/axiosPackaging.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>axios封装</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/monitor.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>前端监控SDK</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/workReview/ImagedragVerification.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>图片拖动验证</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-fe05da0a><section class="VPSidebarItem level-0 collapsible" data-v-fe05da0a data-v-0bb349fd><div class="item" role="button" tabindex="0" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><h2 class="text" data-v-0bb349fd>html/css</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-0bb349fd><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-0bb349fd><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-0bb349fd><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/boxModel.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>盒模型</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/margin.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>margin重叠</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/bfc.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>bfc</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/layout.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>圣杯布局&双飞翼布局</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/dice.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>flex画骰子</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/position.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>position定位</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/align.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>对齐</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/rem-em-vw.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>rem-em-vw</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/grid.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>grid布局</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0bb349fd data-v-0bb349fd><div class="item" data-v-0bb349fd><div class="indicator" data-v-0bb349fd></div><a class="VPLink link link" href="/fe-handbook/document/pages/htmlCss/htmlCss.html" data-v-0bb349fd data-v-f3ed0000><!--[--><p class="text" data-v-0bb349fd>htmlCss总结</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-bffce215 data-v-91952ce3><div class="VPDoc has-sidebar has-aside" data-v-91952ce3 data-v-c11df1f0><!--[--><!--]--><div class="container" data-v-c11df1f0><div class="aside" data-v-c11df1f0><div class="aside-curtain" data-v-c11df1f0></div><div class="aside-container" data-v-c11df1f0><div class="aside-content" data-v-c11df1f0><div class="VPDocAside" data-v-c11df1f0 data-v-cb998dce><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-cb998dce data-v-c834746b><div class="content" data-v-c834746b><div class="outline-marker" data-v-c834746b></div><div class="outline-title" data-v-c834746b>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-c834746b><span class="visually-hidden" id="doc-outline-aria-label" data-v-c834746b> Table of Contents for current page </span><ul class="root" data-v-c834746b data-v-a379eb72><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-cb998dce></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-c11df1f0><div class="content-container" data-v-c11df1f0><!--[--><!--]--><!----><main class="main" data-v-c11df1f0><div style="position:relative;" class="vp-doc _fe-handbook_document_pages_react_react" data-v-c11df1f0><div><h1 id="react18" tabindex="-1">react18 <a class="header-anchor" href="#react18" aria-label="Permalink to &quot;react18&quot;">​</a></h1><ul><li><a href="https://gitee.com/hl-fe/fe-handbook/tree/master/code/react18" target="_blank">源码实现地址</a></li></ul><h2 id="什么是-react" tabindex="-1">什么是 React? <a class="header-anchor" href="#什么是-react" aria-label="Permalink to &quot;什么是 React?&quot;">​</a></h2><ul><li>React 是一个用于构建用户界面的 JavaScript 库</li></ul><h2 id="react-能干什么" tabindex="-1">React 能干什么? <a class="header-anchor" href="#react-能干什么" aria-label="Permalink to &quot;React 能干什么?&quot;">​</a></h2><ul><li>可以通过组件化的方式构建 构建快速响应的大型 Web 应用程序</li></ul><h2 id="组件化" tabindex="-1">组件化 <a class="header-anchor" href="#组件化" aria-label="Permalink to &quot;组件化&quot;">​</a></h2><ul><li>组件化 把页面拆分为一个个组件，方便视图的拆分和复用，还可以做到高内聚和低耦合</li></ul><h2 id="diff算法事件复杂度" tabindex="-1">diff算法事件复杂度 <a class="header-anchor" href="#diff算法事件复杂度" aria-label="Permalink to &quot;diff算法事件复杂度&quot;">​</a></h2><ul><li><p>传统diff算法：</p><ul><li>通过<code>循环递归</code>对节点进行依次对比，算法复杂度达到 <code>O(n^3)</code></li><li>如果要展示1000个节点，得执行上亿次比较。。即便是CPU快能执行30亿条命令，也很难在一秒内计算出差异。</li></ul></li><li><p>React diff:</p></li><li><p>首先，进行<code>同级比较</code>，并非循环比较。</p></li><li><p>这样比较次数就降为<code>一层一次</code>，时间复杂度直接降为<code>O(n)</code></p></li><li><p>如果同级相同位置节点<code>不一样</code>，则<code>直接删除替换</code>，简单粗暴。</p></li></ul><h2 id="什么是-jsx" tabindex="-1">什么是 JSX <a class="header-anchor" href="#什么是-jsx" aria-label="Permalink to &quot;什么是 JSX&quot;">​</a></h2><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>在 React17 以前，babel 是调用的 React.createElement,并且页面需要引入</p><p>在 React17 之后，babel 是调用的(react/jsx-runtimejsx)函数，并且页面无需引入</p></div><ul><li>jsx 是一个语法糖，即可以写 html 也可以写 js</li><li>因为 jsx 在浏览器端是不能被识别的，所以代码在编译阶段会转换成 ReactElement</li><li>ReactElement 就是我们所说的虚拟节点</li></ul><h2 id="createportal" tabindex="-1">createPortal <a class="header-anchor" href="#createportal" aria-label="Permalink to &quot;createPortal&quot;">​</a></h2><ul><li>将组件渲染到对应的容器中<code>ReactDOM.createPortal(child, container)</code></li></ul><h2 id="虚拟的-dom-优缺点" tabindex="-1">虚拟的 dom 优缺点 <a class="header-anchor" href="#虚拟的-dom-优缺点" aria-label="Permalink to &quot;虚拟的 dom 优缺点&quot;">​</a></h2><h3 id="优点" tabindex="-1">优点 <a class="header-anchor" href="#优点" aria-label="Permalink to &quot;优点&quot;">​</a></h3><ul><li>处理了浏览器兼容性问题，避免用户操作真实 DOM</li><li>内容经过了 XSS 处理，可以防范 XSS 攻击</li><li>容易实现跨平台开发 Android、iOS、VR 应用</li><li>更新的时候可以实现差异化更新，减少更新 DOM 的操作</li></ul><h3 id="缺点" tabindex="-1">缺点 <a class="header-anchor" href="#缺点" aria-label="Permalink to &quot;缺点&quot;">​</a></h3><ul><li>不利用SEO</li><li>首屏加载速度慢</li></ul><h2 id="函数组件和类组件的区别" tabindex="-1">函数组件和类组件的区别 <a class="header-anchor" href="#函数组件和类组件的区别" aria-label="Permalink to &quot;函数组件和类组件的区别&quot;">​</a></h2><table><thead><tr><th></th><th>函数组件</th><th>类组件</th></tr></thead><tbody><tr><td>设计理念</td><td>函数式编程</td><td>面向对象编程</td></tr><tr><td>语法形式</td><td>普通函数、箭头函数</td><td>React.Component</td></tr><tr><td>组件实例</td><td>不能实例化没有this</td><td>能实例化，有this</td></tr><tr><td>内部状态</td><td>没有state可以使用，useState代替</td><td>有state</td></tr><tr><td>生命周期</td><td>没有生命周期，可以使用useEffect代替</td><td>有生命周期</td></tr><tr><td>逻辑复用</td><td>使用钩子(hooks)</td><td>定义高阶组件(HOC)</td></tr><tr><td>性能优化</td><td>使用React.memo或useMemo避免组件重复渲染</td><td>使用shouldComponentUpdate避免组件重复渲染</td></tr><tr><td>主要特点</td><td>轻量灵活，容易拆分</td><td>功能全面，逻辑散落</td></tr></tbody></table><h2 id="类组件的的问题" tabindex="-1">类组件的的问题 <a class="header-anchor" href="#类组件的的问题" aria-label="Permalink to &quot;类组件的的问题&quot;">​</a></h2><ul><li>1、类需要实例化，占用堆内存</li><li>2、类的写法比较繁琐，需要继承需要调用父类的构造</li><li>3、代码复用比较繁琐，需要高阶组件，或者minxs</li></ul><h2 id="受控组件-非受控组件" tabindex="-1">受控组件&amp;非受控组件 <a class="header-anchor" href="#受控组件-非受控组件" aria-label="Permalink to &quot;受控组件&amp;非受控组件&quot;">​</a></h2><ul><li>优先使用<code>受控组件</code>，符合 React 设计原则</li><li>必须操作 DOM 时，再使用非受控组件</li></ul><h3 id="受控组件" tabindex="-1">受控组件 <a class="header-anchor" href="#受控组件" aria-label="Permalink to &quot;受控组件&quot;">​</a></h3><ul><li><p>受控组件是指由<code>React组件的状态(state)</code>来控制其<code>表单元素</code>的值或行为的组件。在受控组件中，表单元素的值(如input、textarea、select等)以及其他用户输入的操作，都通过<code>React组件的状态来进行管理和更新</code>。</p></li><li><p>受控组件的特点包括:</p><ul><li>1.状态控制：表单元素的值被保存在React组件的状态中，通过设置状态来控制表单元素的值。</li><li>2.事件处理：通过监听表单元素的事件(如onChange事件)，将用户输入的值更新到组件的状态中。</li><li>3.数据流一致性：React组件的状态是单一数据源，用于更新和渲染表单元素的值。通过确保状态与表单元素的值保持一致，可以实现数据的一致性和同步更新。</li></ul></li></ul><h3 id="非受控组件" tabindex="-1">非受控组件 <a class="header-anchor" href="#非受控组件" aria-label="Permalink to &quot;非受控组件&quot;">​</a></h3><ul><li><p>非受控组件，将表单数据交给<code>DOM节点来处理</code>，可以使用<code>Ref</code>来获取<code>非受控组件</code>的数据，希望能够赋予表单一个初始值，但是<code>不去控制后续的更新</code>。可以采用defaultValue指定一个默认值</p></li><li><p>非受控组件使用场景，必须手动操作DOM元素，state 实现不了，文件上传 <code>&lt;input type=file ref={fileRef}/&gt;</code></p></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useState</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> Controlled</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">React</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">FC</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">setState</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useState</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">string</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">hulei</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">getValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">受控组件</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">input</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">text</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#C792EA;">value</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#C792EA;">onChange</span><span style="color:#89DDFF;">={(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">setState</span><span style="color:#A6ACCD;">(e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">target</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value)</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">      /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">br</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">br</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">getValue</span><span style="color:#89DDFF;">}&gt;</span><span style="color:#A6ACCD;">获取值</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useRef</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useState</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> Uncontrolled</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">React</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">FC</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">setState</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useState</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">string</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">hulei</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">inputRef</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useRef</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">HTMLInputElement</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">null</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">getValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 通过DOM或者到值</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#89DDFF;">?.</span><span style="color:#A6ACCD;">value</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">非受控组件</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">input</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">text</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">defaultValue</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">} </span><span style="color:#C792EA;">ref</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">} /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">br</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">br</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">getValue</span><span style="color:#89DDFF;">}&gt;</span><span style="color:#A6ACCD;">获取值</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span></code></pre></div><h2 id="react-时间分片的大概原理" tabindex="-1">React 时间分片的大概原理 <a class="header-anchor" href="#react-时间分片的大概原理" aria-label="Permalink to &quot;React 时间分片的大概原理&quot;">​</a></h2><ul><li>浏览器<code>刷新频率为 60Hz</code>也就是一秒钟 60 帧,大概 (1000/60)<code>16.6 毫秒渲染一次</code>，而 <code>JS 线程</code>和<code>渲染线程</code>是<code>互斥的</code>，所以如果 JS <code>线程执行任务</code>时间<code>超过 16.6ms</code> 的话，就会导致掉帧，<code>导致卡顿</code>， React <code>利用空闲的时间</code>进行更新，不影响UI渲染进</li><li>把一个耗时任务切分成一个个小任务，<code>分布在每一帧里</code>的方式就叫时间切片</li></ul><p><img src="/fe-handbook/document/assets/lifeofframe.11312989.png" alt="lifeofframe"></p><h2 id="为什么会出现-fiber" tabindex="-1">为什么会出现 fiber <a class="header-anchor" href="#为什么会出现-fiber" aria-label="Permalink to &quot;为什么会出现 fiber&quot;">​</a></h2><ul><li><p>React每次更新都是从根节点开始<code>递归</code>调度并且无法中断，如果 dom 树的结构比较复杂对应的<code>虚拟节点计算会消耗对应的时间</code></p></li><li><p>如果此时用户在进行表单填写操作，会感觉的卡顿，因为<code>js渲染</code>和<code>UI渲染</code>是互斥</p></li><li><p>fiber 架构利用<code>浏览器空闲时间</code>(requestIdleCallback)执行任务，拒绝长时间占用主线程，放弃<code>递归</code>，只采用<code>循环</code>，因为循环可以被中断，任务拆分，将任务拆分成一个个小任务</p></li></ul><h2 id="fiber数据结构" tabindex="-1">fiber数据结构 <a class="header-anchor" href="#fiber数据结构" aria-label="Permalink to &quot;fiber数据结构&quot;">​</a></h2><ul><li>fiber 是一个链表的数据结构，他的 child 指向第一个子节点，sibling 指向最近弟弟，return 指向父 fiber，即使是执行被打断，也很容易恢复</li></ul><p><img src="/fe-handbook/document/assets/Fiber结构.d1bfb141.png" alt="Fiber结构"></p><h2 id="优先级" tabindex="-1">优先级 <a class="header-anchor" href="#优先级" aria-label="Permalink to &quot;优先级&quot;">​</a></h2><h3 id="scheduler优先级" tabindex="-1">scheduler优先级 <a class="header-anchor" href="#scheduler优先级" aria-label="Permalink to &quot;scheduler优先级&quot;">​</a></h3><ul><li>scheduler优先级有5种，每一个优先级对应一个<code>过期时间</code>,过期时间越短，对应优先级越高</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 无优先级 </span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> NoPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 立刻执行优先级(等待时间-1ms)</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ImmediatePriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//用户阻塞操作优先级 用户点击 ，用户输入(等待时间250ms)</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> UserBlockingPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 正常优先级(等待时间5000ms)</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> NormalPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 低优先级(等待时间10000ms)</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> LowPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 空闲优先级(没有过期时间)</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> IdlePriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="lane" tabindex="-1">Lane <a class="header-anchor" href="#lane" aria-label="Permalink to &quot;Lane&quot;">​</a></h2><ul><li>Lane一共有31条车道，对应5种事件优先级</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">/**</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"> * 一共有31条车道</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"> */</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> TotalLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">31</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//没有车道，所有位都为0</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> NoLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> NoLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//同步车道，优先级最高</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> SyncLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000000001</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> SyncBatchedLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000000010</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//离散用户交互车道 click</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputDiscreteHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000000100</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputDiscreteLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000011000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//连续交互车道 mouseMove</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputContinuousHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000000100000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputContinuousLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000011000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//默认车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> DefaultHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000000100000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> DefaultLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000000111000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//渐变车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> TransitionHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000000000000001000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> TransitionLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000000001111111110000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//重试车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> RetryLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000011110000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> SomeRetryLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000010000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//选择性水合车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> SelectiveHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000100000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//非空闲车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> NonIdleLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0000111111111111111111111111111</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> IdleHydrationLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0001000000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//空闲车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> IdleLanes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b0110000000000000000000000000000</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//离屏车道</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> OffscreenLane </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0b1000000000000000000000000000000</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="事件优先级" tabindex="-1">事件优先级 <a class="header-anchor" href="#事件优先级" aria-label="Permalink to &quot;事件优先级&quot;">​</a></h2><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">//离散事件优先级 click onchange</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> DiscreteEventPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> SyncLane</span><span style="color:#89DDFF;">;</span><span style="color:#676E95;font-style:italic;">//1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//连续事件的优先级 mousemove </span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ContinuousEventPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> InputContinuousLane</span><span style="color:#89DDFF;">;</span><span style="color:#676E95;font-style:italic;">//4</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//默认事件车道</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> DefaultEventPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> DefaultLane</span><span style="color:#89DDFF;">;</span><span style="color:#676E95;font-style:italic;">//16 </span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//空闲事件优先级 </span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> IdleEventPriority </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> IdleLane</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="react渲染流程-todo" tabindex="-1">React渲染流程：TODO: <a class="header-anchor" href="#react渲染流程-todo" aria-label="Permalink to &quot;React渲染流程：TODO:&quot;">​</a></h2><ul><li>1、React每次在更新之前都会通过<code>requestUpdateLane函数</code>取当前的<code>Lane优先级</code></li><li>2、通过<code>markUpdateLaneFromFiberToRoot</code>函数，找到<code>Root根节点</code>,并且把当前的Lane合并到<code>pendingLanes</code>上</li><li>3、每次在调度之前，会从<code>Root根节点</code>的pendingLanes，获取一个最高的Lane，如果是<code>NoLane</code>表示没有更新的更新，执行调度器上的Scheduler_cancelCallback调度取消</li><li>4、因为在并发更新时调度是可以中断的，所以需要当前的<code>Lane优先级</code>和上次的Lane进行对比，如果之前的优先级<code>等于</code>当前的优先级, 不需要开启新的调度，scheduler会自动的获取<code>performConcurrentWorkOnRoot</code>的返回函数继续调度</li><li>5、如果当前的<code>Lane优先级</code>比上次的高，取消之前的任务调用，开始新的调度任务</li><li>6、如果是<code>同步Lane</code>优先级，用微任务调度，并且不会走并发更新策略，在<code>构建fiber树</code>时无法中断</li><li>7、如果是非<code>同步Lane</code>优先级，利用<code>Scheduler调度器</code>进行调度，<code>并发更新</code>在<code>构建fiber树</code>时，如果有<code>高优先级</code>的任务或者<code>申请的时间片已经过期了(5毫秒)</code>需要中断构建fiber树</li><li>8、高优先级任务执行完成后，如果还有为完成的任务，需要恢复构建。当所有的fiber构建完成后，执行<code>commitRoot</code>把真实的DOM,渲染在页面上</li></ul><p><img src="/fe-handbook/document/assets/React渲染流程.6a748665.jpeg" alt="React渲染流程"></p><h2 id="scheduler调度器" tabindex="-1">Scheduler调度器 <a class="header-anchor" href="#scheduler调度器" aria-label="Permalink to &quot;Scheduler调度器&quot;">​</a></h2><ul><li>1、Scheduler调度器在执行的时候，接收一个<code>Scheduler优先级</code>和<code>并发更新的任务(performConcurrentWorkOnRoot)</code></li><li>2、根据Scheduler优先级计算出过期的时间，将更新的任务放入<code>最小堆中</code>,并且返回当前的任务</li><li>3、React会在每一帧的空闲时间<code>申请5毫秒的执行时间</code>，每次从最小堆从取出一个<code>堆顶的任务</code>开始执行</li><li>4、如果<code>时间片过期</code>，或者最小堆中还有<code>未完成的任务</code>，将在下一帧继续执行</li></ul><h2 id="fiber树构建过程" tabindex="-1">fiber树构建过程 <a class="header-anchor" href="#fiber树构建过程" aria-label="Permalink to &quot;fiber树构建过程&quot;">​</a></h2><ul><li><p>fiber构建分为三个部分<code>beginWork</code>,<code>completeWork</code>,<code>commitRoot</code></p></li><li><p>1、beginWork阶段，根据虚拟节点<code>构建fiber树</code>标记<code>flags副作用</code>,</p><ul><li>1.1 在构建过程中<code>循环遍历</code>子虚拟节点，让父<code>Fiber.child</code>指向第一个子节点构建的<code>Fiber</code>,让第一个子<code>Fiber.sibling</code>指向下一个兄弟</li><li>1.2 beginWork会返回<code>父Fiber</code>指向的第一个子Fiber，作为下个<code>workInProgress</code>工作单元</li><li>1.3 当一个Fiber没有子Fiber，进入completeWork阶段</li></ul></li><li><p>2、completeWork阶段：根据当前<code>workInProgress</code>的fiber创建真实的DOM节点，赋值给fiber.stateNode</p></li><li><p>3、当所有的fiber节点，都构建完成后进入<code>commitRoot</code>阶段</p></li><li><p>3、commitRoot阶段：从根fiber开始遍历，将fiber节点上的<code>stateNode</code>真实的DOM,插入在对应的容器中，最后渲染到页面上</p></li></ul><h2 id="react-的-diff-原理" tabindex="-1">React 的 Diff 原理 <a class="header-anchor" href="#react-的-diff-原理" aria-label="Permalink to &quot;React 的 Diff 原理&quot;">​</a></h2><ul><li><p>DOM DIFF 的三个规则</p><ul><li>只对同级元素进行比较，不会跨层级</li><li>不同的类型对应不同的元素，可以通过 key 来标识同一个节点</li></ul></li><li><p>组件在渲染的时候，如果有老的Fiber，说明不是首次渲染，需要走更新的策略</p></li><li><p>React更新策略都是用<code>老的Fiber</code>和<code>新的虚拟DOM</code>进行比较，如果<code>key</code>和<code>type</code>类型一样，复用老的 Fiber 节点，如果不一样，根据新的Vnode创建新的Fiber,并且把<code>老的Fiber</code>标记为删除</p></li></ul><h3 id="新的虚拟是单节点" tabindex="-1">新的虚拟是单节点 <a class="header-anchor" href="#新的虚拟是单节点" aria-label="Permalink to &quot;新的虚拟是单节点&quot;">​</a></h3><ul><li>1、循环老的Fiber节点，如果新的虚拟节点的<code>类型(type)</code>和<code>key</code>和老Fiber的一致，复用老的Fiber节点，同时还需要继续循环把剩下的Fiber节点标记为删除</li><li>2、如果新的虚拟节点的<code>类型(type)</code>和<code>key</code>和老Fiber的不一致，当前的Fiber节点标记为删除，通过老<code>Fiber.sibling</code>找下一个Fiber</li><li>3、如果循环完毕后，未能找到能够复用的Fiber节点，需要根据新的虚拟DOM创建新的Fiber节点</li></ul><h3 id="新的虚拟是多节点-多节点分为三种情况" tabindex="-1">新的虚拟是多节点(多节点分为三种情况) <a class="header-anchor" href="#新的虚拟是多节点-多节点分为三种情况" aria-label="Permalink to &quot;新的虚拟是多节点(多节点分为三种情况)&quot;">​</a></h3><ul><li>1、老的Fiber全部能被复用，新的节点还没有遍历完成(新的节点比老的多)</li><li>2、老的Fiber复用了部分，新的节点已经遍历完了(新的节点比老的少)</li><li>3、老的Fiber，新的虚拟DOM,都没有循环完毕(根据老的Fiber生成map对象，遍历还未完成的虚拟DOM，最大程度的复用)</li></ul><p><img src="/fe-handbook/document/assets/diff1.442c337d.png" alt="diff1"></p><p><img src="/fe-handbook/document/assets/diff2.a74ab443.jpg" alt="diff2"></p><ul><li>1、如果有老的Fiber，遍历新的虚拟节点，用<code>老的Fiber</code>和<code>新的虚拟dom</code>进行对比</li><li>2、如果<code>key</code>和<code>type</code>类型相同<code>复用老的 Fiber</code>，否则标记老 Fiber节点为<code>删除</code>，根据新的虚拟DOM创建新的 Fiber,<code>并且跳出当前的循环</code></li><li>3、检测新的虚拟节点是否全部<code>遍历完成</code>，如果新的遍历完成，还有老 Fiber说明更新之后<code>节点变少</code>，需要把剩下的Fiber全部标记为删除</li><li>4、如果老的fiber已经没有了，新的虚拟DOM还有，说明更新之后<code>节点变多</code>进入插入新节点的逻辑</li><li>5、如果老的Fiber，新的虚拟DOM,都没有循环完毕，据老的Fiber生成map对象</li><li>6、遍历<code>剩余</code>的新的虚拟 DOM，如果能复用将老的Fiber<code>从map中移除</code>，如果不能复用，根据新的虚拟 DOM<code>创建Fiber</code></li><li>7、新的虚拟DOM遍历完成后，将 map 所有的 Fiber 标记为删除</li></ul><h2 id="循环链表" tabindex="-1">循环链表 <a class="header-anchor" href="#循环链表" aria-label="Permalink to &quot;循环链表&quot;">​</a></h2><ul><li><p>实现思路:</p><ul><li>1、当fiber更新队列为空时，让新的队列<code>queue1.next</code>指向头节点，让头节点指向<code>queue1</code></li><li>2、当<code>queue2</code>进入队列时，让<code>queue2.next</code>指向头节点的<code>next</code>(queue1),让<code>queue1.next</code>指向<code>queue2</code>(形成循环链表结构),让头节点在指向queue2</li><li>3、当<code>queue3</code>进入队列时，让<code>queue3.next</code>指向头节点(queue2)的<code>next</code>(queue1)，让头节点(queue2.next)指向<code>queue3</code>,让头节点在指向queue3</li></ul></li><li><p>目的:即可以保证链表的顺序也可以减少放入队列的循环次数，在更新状态的时候，需要从第一个进入的队列开始遍历，这里在添加队列的时候只需要改变2个指针，在遍历的时候找最后一个队列的下一个就是头节点，并且让最后一个next指向null</p></li></ul><p><img src="/fe-handbook/document/assets/fiber队列.82fb87b3.png" alt="循环链表"></p><h2 id="合成事件" tabindex="-1">合成事件 <a class="header-anchor" href="#合成事件" aria-label="Permalink to &quot;合成事件&quot;">​</a></h2><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>合成事件好处:可以抹平浏览器事件的兼容性、可以实现跨平台</p></div><ul><li>1、React 容器 在初始化时，会调用 <code>createRoot</code> 在根节点上进行<code>事件注册</code></li><li>2、在创建真实的 dom 的节点时，会把 React 事件挂载到真实的 dom <code>节点属性</code>上</li><li>3、当在触发 React 事件时，通过 event.target，找到点击到DOM，判断节点上有对应的挂载事件</li><li>4、如果有，从当前的事件源向上查找所有的，扑捉、冒泡事件，用于模拟原生的事件</li><li>5、先执行扑捉事件队列，在执行冒泡事件队列</li><li>6、如果有在执行的过程中阻止了默认行为，后续事件不给执行</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 支持的事件类型</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> allNativeEvents </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">click</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> elementEventPropsKey </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">__props</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> listeningMarker </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">_reactListening</span><span style="color:#89DDFF;">`</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> Math</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">random</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">36</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">slice</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 事件映射</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">getEventCallbackNameFromtEventType</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">eventType</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    click</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> [</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">onClickCapture</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">onClick</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">eventType</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 收集从目标元素到HostRoot之间所有目标回调函数</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> collectPaths </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">targetElement</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">container</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">eventType</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">paths</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    capture</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> []</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    bubble</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> []</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 收集事件回调是冒泡的顺序</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">while</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!==</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">container</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// div.__props = {onClickCapture:fn,onClick:fn....}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">eventProps</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">elementEventPropsKey</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">eventProps</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">getEventCallbackNameFromtEventType</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">eventType</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 取出映射的事件</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forEach</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callbackName</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">i</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">          </span><span style="color:#676E95;font-style:italic;">// react事件</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">eventCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">eventProps</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">callbackName</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">eventCallback</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">              </span><span style="color:#676E95;font-style:italic;">// 由于捕获的执行顺序是从上往下，所以是反向收集</span></span>
<span class="line"><span style="color:#89DDFF;">              </span><span style="color:#676E95;font-style:italic;">// 反向插入捕获阶段的事件回调</span></span>
<span class="line"><span style="color:#F07178;">              </span><span style="color:#A6ACCD;">paths</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">capture</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">unshift</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">eventCallback</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">              </span><span style="color:#676E95;font-style:italic;">// 由于冒泡的执行顺序是从下往上，所以是正向收集</span></span>
<span class="line"><span style="color:#89DDFF;">              </span><span style="color:#676E95;font-style:italic;">// 正向插入冒泡阶段的事件回调</span></span>
<span class="line"><span style="color:#F07178;">              </span><span style="color:#A6ACCD;">paths</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">bubble</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">push</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">eventCallback</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">parentNode</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">paths</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> dispatchEvent </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">rootContainerElement</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">eventType</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">target</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// 事件源</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">targetElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">事件不存在target</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 从当前的事件源向上查找所有的，扑捉、冒泡事件，用于模拟原生的事件</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">capture</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">bubble</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">collectPaths</span><span style="color:#F07178;">(</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">targetElement</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">rootContainerElement</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">eventType</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 合成原生事件</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">se</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">createSyntheticEvent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">e</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">triggerEventFlow</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">capture</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">se</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 如果事件被阻止不需要在执行</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">se</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">__stopPropagation</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">triggerEventFlow</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">bubble</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">se</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">listenToAllSupportedEvents</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">rootContainerElement</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">//监听根容器，也就是div#root只监听一次</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">rootContainerElement</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">listeningMarker</span><span style="color:#F07178;">]) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">rootContainerElement</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">listeningMarker</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">allNativeEvents</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forEach</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">eventType</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 注册代理事件</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">rootContainerElement</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">eventType</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">dispatchEvent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">rootContainerElement</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">eventType</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createSyntheticEvent</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">syntheticEvent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">syntheticEvent</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">__stopPropagation</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">false</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 阻止事件传递</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">originStopPropagation</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">stopPropagation</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">syntheticEvent</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">stopPropagation</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">syntheticEvent</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">__stopPropagation</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">originStopPropagation</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">originStopPropagation</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">syntheticEvent</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 执行react事件</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> triggerEventFlow </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">paths</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">se</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#F07178;"> (</span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">paths</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">paths</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">callback</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">null,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">se</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">se</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">__stopPropagation</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">break</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 将支持的事件回调保存在DOM中</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> updateEventProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">node</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">node</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">elementEventPropsKey</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">node</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">elementEventPropsKey</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">||</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">allNativeEvents</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forEach</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">eventType</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 获取支持的事件类型</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">getEventCallbackNameFromtEventType</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">eventType</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 事件映射</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">callbackNameList</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forEach</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callbackName</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hasOwnProperty</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callbackName</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">node</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">elementEventPropsKey</span><span style="color:#F07178;">][</span><span style="color:#A6ACCD;">callbackName</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">callbackName</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">node</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span></code></pre></div><h2 id="react16-版本事件-bug" tabindex="-1">react16 版本事件 bug <a class="header-anchor" href="#react16-版本事件-bug" aria-label="Permalink to &quot;react16 版本事件 bug&quot;">​</a></h2><ul><li><p>比如需要一个事件来控制一个元素的展示，在当前组件注册一个原生的 document 冒泡事件，在处理合成事件让元素展示的时候，如果原生事件处理的是隐藏，其结果就是元素无法展示</p></li><li><p>出现的原因是 react 冒泡事件先注册，注册在 document，所以 react 冒泡事件先执行，后执行原生的 document 冒泡事件，所以无法展示，通过阻止默认行为(冒泡)，无效，因为是同级节点，只能阻止上级</p></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// react16版本</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">App</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">visibility</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">setVisibility</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useState</span><span style="color:#F07178;">(</span><span style="color:#FF9CAC;">false</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 注册冒泡事件</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">click</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">setVisibility</span><span style="color:#F07178;">(</span><span style="color:#FF9CAC;">false</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">handlerClick</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">any</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">setVisibility</span><span style="color:#F07178;">(</span><span style="color:#FF9CAC;">true</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 阻止默认行为(冒泡)，只能阻止上级，不能阻止同级</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">stopPropagation</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 阻止所有</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">nativeEvent</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">stopImmediatePropagation</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">handlerClick</span><span style="color:#89DDFF;">}&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">visibility </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">visibility</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">      点击</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="context-用作原理" tabindex="-1">context 用作原理 <a class="header-anchor" href="#context-用作原理" aria-label="Permalink to &quot;context 用作原理&quot;">​</a></h2><ul><li><p>用作:数据共享，可以避免 props 一层成传递，可以实现跨组件数据共享</p></li><li><p>原理</p><ul><li>1、在创建 createContext 时，会返回一个 context 对象，包含内容提供者(Provider)和消费者(Consumer)，他们都有一个_context 属性,都指向同一个引用地址</li><li>2、react 在渲染时，如果是 Provider 组件，会给组件<code>_context._currentValue</code>进行赋值，在渲染当前的 children 组件</li><li>3、react 在渲染时，如果是 Consumer 组件，会取出<code>_context._currentValue</code>的值，传递给子组件(因为指向同一个引用地址，所以值是一样的)</li><li>4、如果是类组件，有 contextType 属性，会对类上的 context 进行赋值</li></ul></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 渲染provider</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mountProviderComponent</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">vdom</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">type</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// {$$typeof: REACT_PROVIDER,_context: context,};</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 引用赋值</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">type</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">_context</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">_currentValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 用于下次新老做对比(渲染的其实是子元素)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">oldRenderVdom</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">oldRenderVdom</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">createDOM</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 处理函数类件</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mountClassComponent</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">vdom</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> type</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ClassComponent</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ref</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">classInstance</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">ClassComponent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">classInstance</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">classInstance</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 如果有contextType，把context绑定在实例上</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">ClassComponent</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">contextType</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">classInstance</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">context</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ClassComponent</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">contextType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">_currentValue</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// .....</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dom</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createContext</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">context</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> $$typeof</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">REACT_CONTEXT</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 提供者</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">Provider</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    $$typeof</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">REACT_PROVIDER</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    _context</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 消费者</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">Consumer</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    $$typeof</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">REACT_CONTEXT</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    _context</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">red</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> Context </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createContext</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">Context.Provider</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">value</span><span style="color:#89DDFF;">={{</span><span style="color:#F07178;">red</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">color</span><span style="color:#89DDFF;">}}&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;{this.</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">color</span><span style="color:#89DDFF;">}&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#FFCB6B;">Context.Provider</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">Context.Consumer</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">{(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">          </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">style</span><span style="color:#89DDFF;">={{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">color</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">red </span><span style="color:#89DDFF;">}}&gt;</span><span style="color:#A6ACCD;">main</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">span</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#F07178;">      )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}}</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#FFCB6B;">Context.Consumer</span><span style="color:#89DDFF;">&gt;</span></span></code></pre></div><h2 id="react-优化方案-shouldcomponentupdate-purecomponent-memo-usememo-usecallback" tabindex="-1">React 优化方案( shouldComponentUpdate,PureComponent,memo,useMemo,useCallback) <a class="header-anchor" href="#react-优化方案-shouldcomponentupdate-purecomponent-memo-usememo-usecallback" aria-label="Permalink to &quot;React 优化方案( shouldComponentUpdate,PureComponent,memo,useMemo,useCallback)&quot;">​</a></h2><ul><li>类组件 <ul><li>shouldComponentUpdate 组件在更新之前会触发该生命周期，会把上次的 props、state 传递过来，可以根据自己的需求进行对比，如果返回 true,执行更新，如果 false 不更新组件</li><li>PureComponent 内部实现了 shouldComponentUpdate</li></ul></li><li>函数组件 <ul><li>memo 函数组件在更新之前，对比之前的 props,如果未发生变化不执行更新操作 <ul><li>如果未提供 arePropsEqual，React 将对 props 执行浅相等检查。这意味着如果父组件重新渲染并传递相同的 props 对象引用，则子组件不会重新渲染，因为相等检查将通过。</li></ul></li><li>useMemo 缓存值</li><li>useCallback 缓存函数</li></ul></li></ul><h2 id="setstate" tabindex="-1">setState <a class="header-anchor" href="#setstate" aria-label="Permalink to &quot;setState&quot;">​</a></h2><ul><li>在 React 事件中调用 setState，会进行批量更新策略，多个 setState 会进行合并</li><li>在原生事件和异步任务中调度 setState 不会走批处理，相等于同步执行，里面能获取到新的值</li></ul><h2 id="为什么会出现-hooks" tabindex="-1">为什么会出现 hooks <a class="header-anchor" href="#为什么会出现-hooks" aria-label="Permalink to &quot;为什么会出现 hooks&quot;">​</a></h2><ul><li>在 React 16.8 之前，函数组件只能接收 props 作为输入，无法使用 state 和其他 React 特性。React Hooks 则允许我们在函数组件中使用 state、生命周期方法、上下文、Refs 等特性。</li></ul><h2 id="hooks-原理" tabindex="-1">hooks 原理 <a class="header-anchor" href="#hooks-原理" aria-label="Permalink to &quot;hooks 原理&quot;">​</a></h2><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>类组件中的 setState 是状态合并策略 hooks 队列中有多个时，状态不会进行合并，是直接覆盖更新，后者覆盖前者</p></div><ul><li>1、React 在构建 Fiber 时，如果是函数组件首先会调用<code>renderWithHooks</code>进行初始化</li><li>2、构建全局 hooks <code>ReactCurrentDispatcher</code>派发器，如果是首次渲染挂载 Mount<code>HooksDispatcherOnMount</code>、如果是更新挂载 Update<code>HooksDispatcherOnUpdate</code>(派发器就是提供给组件调用的如:useState...)</li><li>3、当函数组件在被调用时，如果是初次渲染，会根据调用的情况，构建 hooks 链表</li><li>4、每一个 hook 都会创建一个更新的队列和一个 dispatchSetState 函数<code>并且已经绑定 fiber, hook队列</code>，并且 next 指向下一个 hook</li><li>5、当 hook 被提交时，其实是调用的 hooks.dispatchSetState 函数，此时会将提交的 新的 State 存储在 hook 队列中，并且触发组件重新渲染</li><li>6、当组件重新渲染时，React 会依据 hooks 链表，按照 hooks 的顺序依次执行对应的函数，从而实现对应的特性。</li></ul><h3 id="hooks-注意事项" tabindex="-1">hooks 注意事项 <a class="header-anchor" href="#hooks-注意事项" aria-label="Permalink to &quot;hooks 注意事项&quot;">​</a></h3><ul><li>因为函数组件所有的 hook,以链表的形式存储的 fiber 中，当函数组件在更新的时候，会按照存储的顺序一个个进行查找</li><li>如果在条件中使用 hooks、或者在循环中使用 hooks，会导致位置出错</li></ul><h2 id="usememo-和-usecallback-区别" tabindex="-1">useMemo 和 useCallback 区别 <a class="header-anchor" href="#usememo-和-usecallback-区别" aria-label="Permalink to &quot;useMemo 和 useCallback 区别&quot;">​</a></h2><ul><li><p>应用场景如需要缓存的函数，因为函数式组件每次任何一个 state 发生变化，会触发整个组件更新，一些函数是没有必要更新的，此时就应该缓存起来，提高性能，减少对资源的浪费；另外还需要注意的是，useCallback 应该和 React.memo 配套使用，缺了一个都可能导致性能不升反而下降。</p></li><li><p>相同点</p><ul><li>1、useMemo 和 useCallback 都是 reactHook 提供的两个 API，用于缓存数据，优化性能；</li><li>2、两者接收的参数都是一样的，第一个参数表示一个回调函数，第二个表示依赖的数据。</li><li>3、在依赖数据发生变化的时候，才会调用传进去的回调函数去重新计算结果，起到一个缓存的作用</li></ul></li><li><p>两者的区别</p><ul><li>1、useMemo 缓存的结果是回调函数中 return 回来的值，主要用于缓存计算结果的值，应用场景如需要计算的状态</li><li>2、useCallback 缓存的结果是函数，主要用于缓存函数</li></ul></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useMemo</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">factory</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">deps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">lastMemo</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 检测依赖的属性是否发生变化</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">every</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">index</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">item</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">index</span><span style="color:#F07178;">])</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 依赖的属性未发生变化返回之前的值</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastMemo</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 返回新的值</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">factory</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 创建新的</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">factory</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">currentMemo</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useCallback</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callback</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">deps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">every</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">index</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">item</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">index</span><span style="color:#F07178;">])</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callback</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">callback</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">currentCallback</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="useeffect-和-uselayouteffect-区别" tabindex="-1">useEffect 和 useLayoutEffect 区别 <a class="header-anchor" href="#useeffect-和-uselayouteffect-区别" aria-label="Permalink to &quot;useEffect 和 useLayoutEffect 区别&quot;">​</a></h2><h3 id="相同点" tabindex="-1">相同点 <a class="header-anchor" href="#相同点" aria-label="Permalink to &quot;相同点&quot;">​</a></h3><ul><li>1、useEffect 和 useLayoutEffect 都是 reactHook 提供的两个 API，可以模拟类组件的部分生命周期</li><li>2、两者接收的参数都是一样的，第一个参数表示一个回调函数(函数可以返回一个函数)，第二个表示依赖的数据。</li><li>3、在依赖数据发生变化的时候，才会调用传进去的回调函数，如果上次之前的函数有返回函数，会在执行回调函数之前执行</li></ul><h3 id="两者的区别-执行回调的时机不用" tabindex="-1">两者的区别(执行回调的时机不用) <a class="header-anchor" href="#两者的区别-执行回调的时机不用" aria-label="Permalink to &quot;两者的区别(执行回调的时机不用)&quot;">​</a></h3><ul><li>1、 useEffect 是在 dom 更新后异步执行</li><li>2、 useLayoutEffect 是在 dom 更新前同步执行（有可能会阻塞 dom 渲染），执行完再更新 dom（useLayoutEffect 可以解决更新 dom 时候屏幕闪烁的问题）</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useEffect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callback</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">deps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">every</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">index</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">item</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">index</span><span style="color:#F07178;">])</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 如果关联的deps未发生变化不做任何操作</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 如果发生变化，执行销毁的回调</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">lastCallback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;font-style:italic;">// 存储新的</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#82AAFF;">callback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// callback 返回的函数，在下次渲染前执行</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#82AAFF;">callback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">deps</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useLayoutEffect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callback</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">dependencies</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">alternate</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hook</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">dependencies</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">dependencies</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">every</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">index</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">item</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastDeps</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">index</span><span style="color:#F07178;">])</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">same</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dependencies</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">lastCallback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// DOM 更新完成后,浏览器绘制之前</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">queueMicrotask</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">callback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#A6ACCD;">lastCallback</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dependencies</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// DOM 更新完成后,浏览器绘制之前</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">queueMicrotask</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">workInProgressFiber</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hooks</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">hookIndex</span><span style="color:#89DDFF;">++</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> [</span><span style="color:#82AAFF;">callback</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dependencies</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="useref-createref区别" tabindex="-1">useRef&amp;createRef区别 <a class="header-anchor" href="#useref-createref区别" aria-label="Permalink to &quot;useRef&amp;createRef区别&quot;">​</a></h2><ul><li>1、都可以在组件中创建<code>ref对象</code>，<code>createRef</code>在<code>类</code>组件<code>函数</code>组件都可以使用，<code>useRef</code>只能在<code>函数</code>组件中使用</li><li>2、在函数组件使用<code>createRef</code>时，每次组件更新都会重新去初始化(指向不同的引用地址)</li><li>3、<code>useRef</code>存储在<code>fiber</code>链表中，每次组件在更新不会重新去初始化(指向相同的引用地址)</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// mount 阶段</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mountRef</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">&gt;(</span><span style="color:#A6ACCD;font-style:italic;">initialValue</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">):</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{|</span><span style="color:#F07178;">current</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;">} {</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 获取 hook 对象</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">hook</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">mountWorkInProgressHook</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">ref</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;">current</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> initialValue</span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">__DEV__</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">seal</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">ref</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 存储</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">hook</span><span style="color:#89DDFF;">.</span><span style="color:#F07178;">memoizedState</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> ref</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">ref</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// update 阶段</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">updateRef</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">&gt;(</span><span style="color:#A6ACCD;font-style:italic;">initialValue</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">):</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{|</span><span style="color:#F07178;">current</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">T</span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;">} {</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">hook</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">updateWorkInProgressHook</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 返回之前的引用</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">hook</span><span style="color:#89DDFF;">.</span><span style="color:#F07178;">memoizedState</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="useref-usestate区别" tabindex="-1">useRef&amp;useState区别 <a class="header-anchor" href="#useref-usestate区别" aria-label="Permalink to &quot;useRef&amp;useState区别&quot;">​</a></h2><ul><li>useState在更新的时候<code>会</code>导致组件重新渲染</li><li>useRef在更新的时候<code>不会</code>导致组件重新渲染</li></ul><h3 id="useref可以解决闭包陷阱问题" tabindex="-1">useRef可以解决闭包陷阱问题 <a class="header-anchor" href="#useref可以解决闭包陷阱问题" aria-label="Permalink to &quot;useRef可以解决闭包陷阱问题&quot;">​</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 1、先点击第一个按钮6次</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2、在点击第二个按钮1次</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 3、立马在点击第一个按钮4次</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useState</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> App </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// setState更新会导致组件更新</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">setState</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useState</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">function</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">handleClick</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 4、由于闭包的特性，当前的值是6，所以打印6</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">},</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">3000</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#676E95;font-style:italic;">/* setState更新会导致组件更新所以是10 */</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">setState</span><span style="color:#A6ACCD;">(state </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}&gt;{</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">}&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">handleClick</span><span style="color:#89DDFF;">}&gt;</span><span style="color:#A6ACCD;">print</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">;</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 1、先点击第一个按钮6次</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2、在点击第二个按钮1次</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 3、立马在点击第一个按钮4次</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useRef</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> App </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useRef</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">function</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">handleClick</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 4、由于都是指向同一个引用地址所以是10</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">},</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">3000</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#89DDFF;">++;</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}}</span></span>
<span class="line"><span style="color:#89DDFF;">      &gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#676E95;font-style:italic;">/* useRef值的改变不会导致组件更新，所以一直是0 */</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">handleClick</span><span style="color:#89DDFF;">}&gt;</span><span style="color:#A6ACCD;">print</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="如何拿到usestate更新的值" tabindex="-1">如何拿到useState更新的值 <a class="header-anchor" href="#如何拿到usestate更新的值" aria-label="Permalink to &quot;如何拿到useState更新的值&quot;">​</a></h2><ul><li>1、可通过<code>useEffect</code>,将更新值作为依赖条件</li><li>2、在更新useState之前，先计算值在更新useState</li></ul><h2 id="forwardref-组件转发" tabindex="-1">forwardRef(组件转发) <a class="header-anchor" href="#forwardref-组件转发" aria-label="Permalink to &quot;forwardRef(组件转发)&quot;">​</a></h2><div class="warning custom-block"><p class="custom-block-title">WARNING</p><ul><li>如果对函数组件，使用<code>ref</code>会抛出如下警告，因为<code>函数组件</code>和<code>类型组件</code>不同，没有实例所以对函数组件直接使用<code>ref</code>是毫无意义的</li><li>Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?</li></ul></div><ul><li>forwardRef可以让父组件的<code>ref</code>获取到子组件的DOM，同时也可以配合<code>useImperativeHandle</code>,将子组件的函数暴露给父组件<code>ref</code></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useEffect</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">useRef</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">forwardRef</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputText </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">any</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ref</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">any</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">input</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">ref</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">ref</span><span style="color:#89DDFF;">} /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ForwardInput </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">forwardRef</span><span style="color:#A6ACCD;">(InputText)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">React</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">FC</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">inputRef</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useRef</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">HTMLInputElement</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">null</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">useEffect</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 获取到子组件的input</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">focus</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">ForwardInput</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">ref</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">}&gt;&lt;/</span><span style="color:#FFCB6B;">ForwardInput</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">;</span></span></code></pre></div><ul><li>1、forwardRef是一个函数组件，它接收一个组件，返回一个对象，包含<code>$$typeof</code>类型,和<code>render</code>(render是外部传递的组件),</li><li>3、当组件在渲染的时候，内部会保留父组件传递的<code>ref的引用</code>，如果是<code>$$typeof</code>类型是<code>REACT_FORWARD_REF</code>,调用<code>render</code>渲染组件，并且把props,ref传递给对应的组件</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">forwardRef</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">render</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    $$typeof</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">REACT_FORWARD_REF</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">render</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> (type </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> type</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">$$typeof </span><span style="color:#89DDFF;">===</span><span style="color:#A6ACCD;"> REACT_FORWARD_REF) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mountForwardComponent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vdom</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">mountForwardComponent</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">vdom</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">type</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ref</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vdom</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">renderVdom</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">type</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">render</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ref</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">renderVdom</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">createDOM</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">renderVdom</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="useimperativehandle" tabindex="-1">useImperativeHandle <a class="header-anchor" href="#useimperativehandle" aria-label="Permalink to &quot;useImperativeHandle&quot;">​</a></h2><ul><li>1、useImperativeHandle其实就是一个普通的函数，接受<code>2个参数</code>一个是父组件的<code>ref</code>,另外是一个函数返回一个对象</li><li>2、当useImperativeHandle在被调用时，内部会调用第二个参数将返回的对象,存储在父组件<code>ref.current</code></li><li>3、因为是同一个引用地址，所以通过父组件的<code>ref.current</code>能够调用到子组件的定义的函数</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">useEffect</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">useRef</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">forwardRef</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">useImperativeHandle</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">interface</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">IInputText</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">onClick</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">void</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> InputText </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">any</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ref</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">any</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">useImperativeHandle</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">ref</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">onClick</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">子组件的函数</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ForwardInput </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">forwardRef</span><span style="color:#A6ACCD;">(InputText)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">React</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">FC</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">inputRef</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useRef</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">IInputText</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">null</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">useEffect</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">onClick</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">ForwardInput</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">ref</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">inputRef</span><span style="color:#89DDFF;">}&gt;&lt;/</span><span style="color:#FFCB6B;">ForwardInput</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> App</span><span style="color:#89DDFF;">;</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 实现</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useImperativeHandle</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ref</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">handler</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">ref</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">current</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">handler</span><span style="color:#F07178;">()</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><h2 id="react-新增了什么生命周和删除了什么生命周期-为什么要删除" tabindex="-1">react 新增了什么生命周和删除了什么生命周期，为什么要删除 <a class="header-anchor" href="#react-新增了什么生命周和删除了什么生命周期-为什么要删除" aria-label="Permalink to &quot;react 新增了什么生命周和删除了什么生命周期，为什么要删除&quot;">​</a></h2><ul><li>1、componentWillMount、2、componentWillUpdate 3、componentWillReceiveProps</li><li>React 废弃的这三个生命周期函数，大都是因为新版本的异步渲染，在调用 render 生成虚拟 DOM 阶段，由于更高级的操作到来而被打断,导致 render 之前的操作都会重来。使得之前的逻辑可能会被重复调用而弃用。</li></ul><h2 id="vue-vs-react" tabindex="-1">Vue vs React <a class="header-anchor" href="#vue-vs-react" aria-label="Permalink to &quot;Vue vs React&quot;">​</a></h2><ul><li><p>Vue使用模版拥抱html</p></li><li><p>Vue 是真正意义上的做到了组件级更新，每一个组件就对应一个渲染的 effect，让响应式数据去收集 effect</p></li><li><p>Vue 采用的是递归的方式来渲染页面不可中断</p></li><li><p>React使用的JSX拥抱JS</p></li><li><p>React 更新都是从跟节点开始调度，会讲一个大的任务拆分成多个小的任务单元</p></li><li><p>React 更新策略是循环的方式，有任务优先级的概念，可中断执行</p></li></ul><h2 id="react错误处理componentdidcatch、useerrorboundary" tabindex="-1">React错误处理<code>componentDidCatch</code>、<code>useErrorBoundary</code> <a class="header-anchor" href="#react错误处理componentdidcatch、useerrorboundary" aria-label="Permalink to &quot;React错误处理`componentDidCatch`、`useErrorBoundary`&quot;">​</a></h2><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">ErrorBoundary</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">super</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> hasError</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">false</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">componentDidCatch</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">error</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">info</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> hasError</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">};</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hasError</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;font-style:italic;">// 显示备用 UI</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">Something went wrong.</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">&gt;;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> ErrorBoundary</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">App</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">ErrorBoundary</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">Hello, world!</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#FFCB6B;">ErrorBoundary</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ErrorBoundary</span><span style="color:#89DDFF;">({</span><span style="color:#A6ACCD;font-style:italic;">children</span><span style="color:#89DDFF;">}:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;">children</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">ReactNode</span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">errorMsg</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">updateError</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">useState</span><span style="color:#89DDFF;">&lt;</span><span style="color:#FFCB6B;">Error</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">|</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">null</span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">null</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">useErrorBoundary</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Error</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">updateError</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">e</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">errorMsg </span><span style="color:#89DDFF;">?</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">报错：</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> errorMsg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">() </span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> children</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#F07178;">  )</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div></div></div></main><footer class="VPDocFooter" data-v-c11df1f0 data-v-fc0d1b73><!--[--><!--]--><div class="edit-info" data-v-fc0d1b73><!----><div class="last-updated" data-v-fc0d1b73><p class="VPLastUpdated" data-v-fc0d1b73 data-v-0de45606>上次更新: <time datetime="2024-02-21T09:31:46.000Z" data-v-0de45606></time></p></div></div><div class="prev-next" data-v-fc0d1b73><div class="pager" data-v-fc0d1b73><a class="pager-link prev" href="/fe-handbook/document/pages/vue/vuex4.0.html" data-v-fc0d1b73><span class="desc" data-v-fc0d1b73>Previous page</span><span class="title" data-v-fc0d1b73>vuex4.0</span></a></div><div class="has-prev pager" data-v-fc0d1b73><a class="pager-link next" href="/fe-handbook/document/pages/react/redux.html" data-v-fc0d1b73><span class="desc" data-v-fc0d1b73>Next page</span><span class="title" data-v-fc0d1b73>redux</span></a></div></div></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"pages_advancedprogramming_chapterone.md\":\"8fd81287\",\"pages_htmlcss_layout.md\":\"f07c901d\",\"index.md\":\"4ccfffb7\",\"pages_advancedprogramming_index.md\":\"3885217d\",\"code_fe-rec_readme.md\":\"71d0c648\",\"readme.md\":\"df521108\",\"code_virtual-list_readme.md\":\"17e862f9\",\"pages_guide.md\":\"706d8779\",\"pages_jsbase_typeconversion.md\":\"df6df8ff\",\"pages_htmlcss_bfc.md\":\"21d6a345\",\"pages_jsbase_cookielocal.md\":\"07b498fe\",\"pages_jsbase_datatype.md\":\"6076c1b6\",\"pages_jsbase_prototype.md\":\"6b57d6e9\",\"pages_htmlcss_htmlcss.md\":\"8b4e53c2\",\"pages_advancedprogramming_chaptertwo.md\":\"ad76f5b8\",\"pages_advancedprogramming_chapterthree.md\":\"8207f883\",\"pages_htmlcss_align.md\":\"8cc3e186\",\"pages_git.md\":\"5308b89e\",\"pages_jsbase_arrayapi.md\":\"751b1dff\",\"pages_htmlcss_boxmodel.md\":\"498a703b\",\"pages_htmlcss_position.md\":\"c5594a7c\",\"pages_jsbase_binary.md\":\"9b13b269\",\"pages_htmlcss_dice.md\":\"cc205c39\",\"pages_workreview_vuexpersistence.md\":\"1df9efec\",\"pages_workreview_reduxpersistence.md\":\"2f4f8ba5\",\"pages_webpack.md\":\"e8ec95fb\",\"pages_jsbase_scope.md\":\"268d233b\",\"pages_vue_vuex4.0.md\":\"98700d83\",\"pages_workreview_reactsolt.md\":\"2438b161\",\"pages_jsbase_this.md\":\"9d7c8fa7\",\"pages_workreview_virtuallist.md\":\"1db3bb5e\",\"code_big-files-upload_index.md\":\"49cc321f\",\"pages_jsbase_regular.md\":\"fea9b33d\",\"pages_jsbase_eventloop.md\":\"ddceb0f2\",\"pages_htmlcss_rem-em-vw.md\":\"f5e61910\",\"pages_optimize.md\":\"9b05a225\",\"pages_jsbase_promotion.md\":\"7da50ccc\",\"pages_jsbase_eightleggedessay.md\":\"560c41b2\",\"pages_jsbase_promise.md\":\"3d80d27b\",\"pages_vue_vuerouter4.0.md\":\"5ca24aaa\",\"pages_htmlcss_margin.md\":\"6fd000ce\",\"pages_flutter_index.md\":\"b69ef00b\",\"pages_workreview_interfacesignaturedesign.md\":\"98a64266\",\"pages_workreview_stripe.md\":\"68fbf713\",\"pages_http.md\":\"42149b78\",\"pages_nginx.md\":\"76adfb79\",\"pages_nodejs_nest.md\":\"340072bd\",\"pages_updatelog.md\":\"3a8f3b74\",\"pages_linux.md\":\"db194270\",\"pages_nodejs_index.md\":\"b91cc4fe\",\"pages_ssr.md\":\"29ae7526\",\"pages_vue_vue2.0.md\":\"ddaba816\",\"pages_resume.md\":\"e770c83b\",\"pages_react_react.md\":\"dd542d19\",\"pages_workreview_monitor.md\":\"bef20b19\",\"pages_react_redux.md\":\"a3c335fe\",\"pages_workreview_bigfileupload.md\":\"93f0370f\",\"pages_datastructure.md\":\"60632978\",\"pages_workreview_imagecroppingcompression.md\":\"3273dca0\",\"pages_jsbase_coding.md\":\"fd837602\",\"pages_xss-csrf.md\":\"afbef4b3\",\"pages_designpatterns.md\":\"7ba6c4c8\",\"pages_workreview_imagedragverification.md\":\"de2e29d5\",\"pages_workreview_audio.md\":\"e00ea8e1\",\"pages_workreview_axiospackaging.md\":\"e241a1bb\",\"pages_htmlcss_grid.md\":\"fee00858\",\"pages_vue_vue3.0.md\":\"21ba1254\",\"pages_jsbase_typescript.md\":\"48ee2090\"}")
__VP_SITE_DATA__ = JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"前端码农\",\"description\":\"前端码农手记\",\"base\":\"/fe-handbook/document/\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"lastUpdatedText\":\"上次更新\",\"logo\":\"images/logo.svg\",\"nav\":[{\"text\":\"主页\",\"link\":\"/\"},{\"text\":\"指南\",\"link\":\"/pages/guide\"},{\"text\":\"更新日志\",\"link\":\"/pages/updateLog\"}],\"socialLinks\":[],\"sidebar\":[{\"collapsed\":false,\"items\":[{\"text\":\"开发指南\",\"link\":\"/pages/guide\"}]},{\"text\":\"JavaScript高级程序设计\",\"collapsed\":false,\"items\":[{\"text\":\"0.前言\",\"link\":\"/pages/advancedProgramming/index.md\"},{\"text\":\"1.什么是JavaScript\",\"link\":\"/pages/advancedProgramming/chapterOne.md\"},{\"text\":\"2.HTML中的JavaScript\",\"link\":\"/pages/advancedProgramming/chapterTwo.md\"},{\"text\":\"3.语言基础\",\"link\":\"/pages/advancedProgramming/chapterThree.md\"}]},{\"text\":\"vue技术栈\",\"collapsed\":false,\"items\":[{\"text\":\"vue2.0\",\"link\":\"/pages/vue/vue2.0.md\"},{\"text\":\"vue3.0\",\"link\":\"/pages/vue/vue3.0.md\"},{\"text\":\"vuex4.0\",\"link\":\"/pages/vue/vuex4.0.md\"}]},{\"text\":\"react技术栈\",\"collapsed\":false,\"items\":[{\"text\":\"react18\",\"link\":\"/pages/react/react.md\"},{\"text\":\"redux\",\"link\":\"/pages/react/redux.md\"}]},{\"text\":\"nodejs技术栈\",\"collapsed\":false,\"items\":[{\"text\":\"nodeJS\",\"link\":\"/pages/nodeJS/index.md\"},{\"text\":\"nest\",\"link\":\"/pages/nodeJS/nest.md\"}]},{\"text\":\"flutter\",\"collapsed\":false,\"items\":[{\"text\":\"flutter\",\"link\":\"/pages/flutter/index.md\"}]},{\"text\":\"数据结构算法&设计模式\",\"collapsed\":false,\"items\":[{\"text\":\"dataStructure\",\"link\":\"/pages/dataStructure.md\"},{\"text\":\"设计模式\",\"link\":\"/pages/designPatterns.md\"}]},{\"text\":\"js基础进阶\",\"collapsed\":false,\"items\":[{\"text\":\"数据类型\",\"link\":\"/pages/jsBase/dataType.md\"},{\"text\":\"数据类型转换\",\"link\":\"/pages/jsBase/typeConversion.md\"},{\"text\":\"原型与原型链\",\"link\":\"/pages/jsBase/prototype.md\"},{\"text\":\"闭包\",\"link\":\"/pages/jsBase/scope.md\"},{\"text\":\"this指针\",\"link\":\"/pages/jsBase/this.md\"},{\"text\":\"JS中的变量提升和函数提升\",\"link\":\"/pages/jsBase/promotion.md\"},{\"text\":\"异步&事件循环机制\",\"link\":\"/pages/jsBase/eventLoop.md\"},{\"text\":\"promise\",\"link\":\"/pages/jsBase/promise.md\"},{\"text\":\"cookie&local\",\"link\":\"/pages/jsBase/cookieLocal.md\"},{\"text\":\"arrayApi\",\"link\":\"/pages/jsBase/arrayApi.md\"},{\"text\":\"正则\",\"link\":\"/pages/jsBase/regular.md\"},{\"text\":\"coding\",\"link\":\"/pages/jsBase/coding.md\"},{\"text\":\"typescript\",\"link\":\"/pages/jsBase/typescript.md\"}]},{\"text\":\"前端综合\",\"collapsed\":false,\"items\":[{\"text\":\"前端八股文\",\"link\":\"/pages/jsBase/eightLeggedEssay.md\"},{\"text\":\"二进制\",\"link\":\"/pages/jsBase/binary.md\"},{\"text\":\"ssr\",\"link\":\"/pages/ssr.md\"},{\"text\":\"webpack\",\"link\":\"/pages/webpack.md\"},{\"text\":\"http\",\"link\":\"/pages/http.md\"},{\"text\":\"性能优化\",\"link\":\"/pages/optimize.md\"},{\"text\":\"xss-csrf\",\"link\":\"/pages/xss-csrf.md\"},{\"text\":\"linux\",\"link\":\"/pages/linux.md\"},{\"text\":\"nginx\",\"link\":\"/pages/nginx.md\"},{\"text\":\"git管理\",\"link\":\"/pages/git.md\"}]},{\"text\":\"工作复盘\",\"collapsed\":false,\"items\":[{\"text\":\"stripe支付体检优化\",\"link\":\"/pages/workReview/stripe.md\"},{\"text\":\"接口签名设计\",\"link\":\"/pages/workReview/interfaceSignatureDesign.md\"},{\"text\":\"redux数据持久化\",\"link\":\"/pages/workReview/reduxpersistence.md\"},{\"text\":\"vuex数据持久化\",\"link\":\"/pages/workReview/vuexpersistence.md\"},{\"text\":\"react插槽设计\",\"link\":\"/pages/workReview/reactSolt.md\"},{\"text\":\"大文件上传\",\"link\":\"/pages/workReview/bigfileUpload.md\"},{\"text\":\"音频录制\",\"link\":\"/pages/workReview/audio.md\"},{\"text\":\"虚拟列表\",\"link\":\"/pages/workReview/virtuaLlist.md\"},{\"text\":\"图片裁剪&压缩\",\"link\":\"/pages/workReview/imageCroppingCompression.md\"},{\"text\":\"axios封装\",\"link\":\"/pages/workReview/axiosPackaging.md\"},{\"text\":\"前端监控SDK\",\"link\":\"/pages/workReview/monitor.md\"},{\"text\":\"图片拖动验证\",\"link\":\"/pages/workReview/ImagedragVerification.md\"}]},{\"text\":\"html/css\",\"collapsed\":false,\"items\":[{\"text\":\"盒模型\",\"link\":\"/pages/htmlCss/boxModel.md\"},{\"text\":\"margin重叠\",\"link\":\"/pages/htmlCss/margin.md\"},{\"text\":\"bfc\",\"link\":\"/pages/htmlCss/bfc.md\"},{\"text\":\"圣杯布局&双飞翼布局\",\"link\":\"/pages/htmlCss/layout.md\"},{\"text\":\"flex画骰子\",\"link\":\"/pages/htmlCss/dice.md\"},{\"text\":\"position定位\",\"link\":\"/pages/htmlCss/position.md\"},{\"text\":\"对齐\",\"link\":\"/pages/htmlCss/align.md\"},{\"text\":\"rem-em-vw\",\"link\":\"/pages/htmlCss/rem-em-vw.md\"},{\"text\":\"grid布局\",\"link\":\"/pages/htmlCss/grid.md\"},{\"text\":\"htmlCss总结\",\"link\":\"/pages/htmlCss/htmlCss.md\"}]}]},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}")</script>
    
  </body>
</html>